package com.epalmpay.controller.apiweixin;

import java.io.IOException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.epalmpay.commom.BaseController;
import com.epalmpay.enumdef.BizEnum;
import com.epalmpay.plugin.MyWxMpConfigStorage;
import com.epalmpay.service.management.ITemplateMailSendService;
import com.epalmpay.service.weixin.IWxBaseService;
import com.epalmpay.service.weixin.impl.WxService;
import com.epalmpay.util.HttpClientUtil;
import com.epalmpay.util.PageData;

import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;

/**
 * 
* 类名称：WechatController.java
* 类描述： 微信公众号开发入口
* @author zsj 
* 创建时间：2017年5月18日
 */
@Controller
@RequestMapping(value="/wechat")
public class WechatController extends BaseController{
	     
   

	@Autowired
    protected WxService wxService;
    
    @Autowired
    protected IWxBaseService wxBaseService;
    
    @Autowired
    @Lazy
    private ITemplateMailSendService templateMailSendService;
	    
	 @RequestMapping(value="serverno",method = {RequestMethod.GET,RequestMethod.POST} )
	 public void index(HttpServletRequest request, HttpServletResponse response
			 ) throws Exception{    
		 logBefore(logger, "------------------------------------微信入口------------------------------------");
		 PageData pd = new PageData();
		 response.setContentType("text/html;charset=UTF-8"); 
		 pd = this.getPageData();
		 String signature = pd.getString("signature");		//微信加密签名
		 String timestamp = pd.getString("timestamp");		//时间戳
		 String nonce	  = pd.getString("nonce");			//随机数
		 String echostr   = pd.getString("echostr");			//字符串	
		 String groupId   = pd.getString("groupId");				
		 //所有使用wxService 前 设置 WxMpInMemoryConfigStorage
		 if(StringUtils.isBlank(groupId)){
			 return ;
		 }
		 
		 MyWxMpConfigStorage wxMpConfigStorage= wxBaseService.getTokenByGroupId(Long.parseLong(groupId));
		 if(wxMpConfigStorage==null){
			 return ;
		 }
		 String httpUrl=wxMpConfigStorage.getWxNotifyUrl();
		 StringBuffer buffer=new StringBuffer();
		 if(StringUtils.isNotBlank(httpUrl)){
			 buffer.append(httpUrl);
			 if(StringUtils.isNotBlank(signature)){
			 buffer.append("&signature=").append(signature);
			 }
			 if(StringUtils.isNotBlank(timestamp)){
			 buffer.append("&timestamp=").append(timestamp);
			 }
			 if(StringUtils.isNotBlank(nonce)){
				 buffer.append("&nonce=").append(nonce);
			 }	
			 if(StringUtils.isNotBlank(echostr)){
			    buffer.append("&echostr=").append(echostr);
			 }
			 if(StringUtils.isNotBlank(groupId)){
				 buffer.append("&groupId=").append(groupId);
			 }
		 }
		
		 
		 wxService.setWxMpConfigStorage(wxMpConfigStorage);
		
		 
		 
		try {
			 String desSignature= SHA1.gen(wxMpConfigStorage.getToken(), timestamp, nonce);
			 System.out.println("getToken::"+wxMpConfigStorage.getToken()+"-------------timestamp:::"+timestamp+"---nonce:::"+nonce);
			 System.out.println("desSignature::"+desSignature+"-------------signature:::"+signature);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
		
		 if (!this.wxService.checkSignature(timestamp, nonce, signature)) {
	            // 消息签名不正确，说明不是公众平台发过来的消息
	            response.getWriter().println("非法请求");
	            return;
	        }
	        if (StringUtils.isNotBlank(echostr)) {
	            // 说明是一个仅仅用来验证的请求，回显echostr
	            String echoStrOut = String.copyValueOf(echostr.toCharArray());
	            response.getWriter().println(echoStrOut);
	            if(StringUtils.isNotBlank(httpUrl)){
	            	  HttpClientUtil.get(buffer.toString());
	            }	          
	            return;
	        }
	        String encryptType = StringUtils.isBlank(pd.getString("encrypt_type"))
	                ? "raw"
	                : request.getParameter("encrypt_type");
	        request.getInputStream();
	        
	        if ("raw".equals(encryptType)) {
                // 明文传输的消息
	        	String inMessageXml=readContent(request);
	        	buffer.append("&encrypt_type=").append("raw");		
                WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(inMessageXml);            
                WxMpXmlOutMessage outMessage = this.wxService.route(inMessage);
                String outXml=outMessage.toXml();
                response.getWriter().write(outXml);
                if(StringUtils.isNotBlank(httpUrl)){
                	 HttpClientUtil.post(buffer.toString(), inMessageXml);
	            }
               
                return;
            }
	        if ("aes".equals(encryptType)) {
	            // 是aes加密的消息
	        	 String msgSignature =pd.getString("msg_signature");
	        	 if(StringUtils.isNotBlank(msgSignature)){
	    			 buffer.append("&msg_signature=").append(msgSignature);
	    		 }
	        	 buffer.append("&encrypt_type=").append("raw");	
	        	 String inMessageXml=readContent(request);
	        	
	            WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(
	            		inMessageXml, wxService.getWxMpConfigStorage(), timestamp, nonce,
	                msgSignature);
	            logBefore(logger, "消息解密后内容为"+inMessage.toString());
	            WxMpXmlOutMessage outMessage = this.wxService.route(inMessage);
	            response.getWriter().write(outMessage.toEncryptedXml(wxService.getWxMpConfigStorage()));
	            if(StringUtils.isNotBlank(httpUrl)){
               	 HttpClientUtil.post(buffer.toString(), inMessageXml);
	            }
	            return;
	        }          
	        response.getWriter().println("不可识别的加密类型");
	        return;
	}
	  
	 
	 private String  readContent( HttpServletRequest request ) throws IOException {
		 ServletInputStream sis=request.getInputStream();  
         // 取HTTP请求流长度    
         int size = request.getContentLength();    
         // 用于缓存每次读取的数据    
         byte[] buffer = new byte[size];    
         // 用于存放结果的数组    
         byte[] xmldataByte = new byte[size];    
         int count = 0;    
         int rbyte = 0;    
         // 循环读取    
         while (count < size) {     
             // 每次实际读取长度存于rbyte中    
             rbyte = sis.read(buffer);     
             for(int i=0;i<rbyte;i++) {    
                 xmldataByte[count + i] = buffer[i];    
             }    
             count += rbyte;    
         }                  
         return new String(xmldataByte, "UTF-8"); 
	 }
	 
	 
	 
	 @RequestMapping(value="test",method = {RequestMethod.GET,RequestMethod.POST} )
	 public void test(HttpServletRequest request, HttpServletResponse response,String memberId) throws Exception{    
		 
		 try {
	            templateMailSendService.sendMemberTemplate(Long.valueOf(memberId), BizEnum.WebTemplateType.template1.getType(), ROOT_HOME_URL, null);
	        } catch (Exception e) {
	            System.out.println("模板消息发送失败" + e);
	            e.printStackTrace();
	        }
	        return;
	}
	
	 
}
